package com.lolaage.tsr.dals.po;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.log4j.Logger;

import com.lolaage.tsr.dals.base.IBaseDao;
import com.lolaage.tsr.dals.base.SpringDaoImpl;
import com.lolaage.tsr.dals.util.ContextUtil;


/**
 * 
 * @author dengpeng
 * 2013-4-28 下午03:29:14
 */
public class SensitiveMessageFilterUtil {
	private static Logger log = Logger.getLogger(SensitiveMessageFilterUtil.class);
	private static List<String> sensitiveMessages=new ArrayList<String>();
	private static String fileServeraddr = ContextUtil.getInitConfig("file.server.addr");
	public static List<String> getSensitiveMessages() {
		return sensitiveMessages;
	}

	static {
		try {
			if(fileServeraddr!=null&&!"".endsWith(fileServeraddr.trim())){
				fileServeraddr+="f/d";
				reloadSensitiveMessageCache();
				log.info("The system load sensitive words success...");
			}else{
				log.info("The system does not use the sensitive words!");
			}
		} catch (Exception e) {
			log.warn("load sensitive words error...");
		}
	}
	public static void main(String[] args) {
		System.out.println(SensitiveMessageFilterUtil.filterContent("法轮功法轮"));
		System.out.println(SensitiveMessageFilterUtil.filterContent("太阳神教"));
		System.out.println(new String((byte[]) SensitiveMessageFilterUtil.filterContent("法轮功法轮".getBytes())));
	}
	public static void reloadSensitiveMessageCache() throws Exception {
		IBaseDao dao = null;
		try {
			dao = (IBaseDao) ContextUtil.getBean("coreDao");
		} catch (Exception e) {
			dao = new SpringDaoImpl();
		}
		String sql = "select f_file_id from t_sensitive_word order by f_id desc limit 0,1";
		List<Long> fileIdList = dao.queryBySql(Long.class, sql, null);
		for (Long fileId : fileIdList) {
			Map<String, String> params = new HashMap<String, String>();
			params.put("fileid", Long.toString(fileId));// 文件ID
			params.put("fileType",String.valueOf(-1));// 文件类型0-图片，1-音频，2-视频 3-轨迹 4-地图涂鸦
			params.put("spec", "0");// 图片规格0-原图，1-缩略图100X100(文件类型为1时需要)
			params.put("userId", "-99999");// 用户ID
			params.put("sessionId", "-99999");// 用户SESSIONID
			params.put("begin", String.valueOf("0"));
			//filePath=filePath+resBean.getFileInfo().getFileName();
			InputStream in = downloadAsStream(params);
			if(in != null){
			    sensitiveMessages = new ArrayList<String>();
			}
			BufferedReader reader = new BufferedReader(new InputStreamReader(in,"UTF-8"));
			String line = null;
			while ((line = reader.readLine()) != null) {
				if (line != null && !"".equals(line.trim())) {
					sensitiveMessages.add(line.trim());
				}
			}
		}
	}

	public static String getDownloadUrl(Map<String, String> params) throws UnsupportedEncodingException {
		StringBuilder paramStr = new StringBuilder("");
		if (params != null) {
			for (String key : params.keySet()) {
				if (paramStr.length() > 0)
					paramStr.append("&");
				paramStr.append(key).append("=")
						.append(URLEncoder.encode(params.get(key), "UTF-8"));
			}
		}
		

		
		return fileServeraddr + (paramStr!=null&&paramStr.length()>0?"?" + paramStr.toString():"");
	}
	public static InputStream downloadAsStream(Map<String, String> params) throws Exception {
		String url = getDownloadUrl(params);//下载的URL地址
		HttpMethod method = new GetMethod(url);
		HttpClient client = new HttpClient();
		client.getHttpConnectionManager().getParams().setConnectionTimeout(15000);
		
		
		int status = client.executeMethod(method);
		if (status == HttpStatus.SC_OK) {
			return method.getResponseBodyAsStream();
		}
		return null;
	}
	/**
	 * 过滤对象中的敏感信息
	 * 
	 * @param obj
	 * @return
	 */
	public static Object filterContent(Object obj) {
		if (obj == null)
			return null;
		return replaceSensitiveMessage(obj);
	}
	private static int count = 0;
	public static boolean isHaveSensitiveMessage(Object obj) {
		count = 0;
		replaceSensitiveMessage(obj);
		return count > 0;
	}
	
	public static boolean isHaveSensitiveMessage(byte[] obj) {
		count = 0;
		doFilter(new String((byte[]) obj)).getBytes();
		return count > 0;
	}

	private static Object replaceSensitiveMessage(Object obj) {
		if (obj instanceof Map) {
			Map<Object, Object> map = (Map<Object, Object>) obj;
			Set<Object> keys = map.keySet();
			for (Object key : keys) {
				Object value = map.get(key);
				map.put(key, replaceSensitiveMessage(value));
			}
		} else {
				if (obj instanceof String) {
					if (obj != null && !"".equals(obj))
						return doFilter(obj.toString());
				} else if (obj instanceof Object[]) {
					Object[] arr = (Object[]) obj;
					for (int i = 0; i < arr.length; i++) {
						arr[i] = replaceSensitiveMessage(arr[i]);
					}
					return arr;
				}else if (obj instanceof Collection) {
					Collection c = (Collection) obj;
					for (Object o : c) {
						replaceSensitiveMessage(o);
					}
				} else if (!isStandardType(obj)) {
					if (!obj.getClass().equals(Class.class) && !obj.getClass().equals(Object.class)) {
						Method[] methods = obj.getClass().getMethods();
						for (Method method : methods) {
							String methodName = method.getName();
							if (!methodName.startsWith("get")) continue;
							String setterName = "s" + methodName.substring(1);
							Object value = null;
							try {
								value = method.invoke(obj, new Object[] {});
							} catch (Exception e) {
								//找不到方法或执行方法失败，继续执行循环
								continue ;
							}
							if (value == null || "".equals(value)) continue;
							for (Method setter : methods) {
								if (setter.getName().equals(setterName)) {
									try {
										if (method.getReturnType().equals(String.class)) {
											setter.invoke(obj, doFilter(value.toString()));
										} else {
											setter.invoke(obj, replaceSensitiveMessage(value));
										}
									} catch (Exception e) {
										//执行setter失败，匹配下一个方法
									}
								}
							}
						}
					}
				}

		}
		return obj;
	}

	/**
	 * 是否基础类型(包括一些不需要过滤的类型)
	 * @param obj
	 * @return
	 */
	private static boolean isStandardType(Object obj) {
		if (obj instanceof Number || obj instanceof Boolean || obj instanceof Byte || obj instanceof Date
				|| obj instanceof Character || obj instanceof BigDecimal)
			return true;
		return false;
	}

	/**
	 * 替换敏感信息
	 * 
	 * @param value
	 * @return
	 */
	private static String doFilter(String value) {
		if(sensitiveMessages==null||sensitiveMessages.size()==0)return value;
		// TODO 处理所有敏感信息过滤
		for (String key : sensitiveMessages) {
			String temp = value;
			value = value.replace(key, "**");
			if (!temp.equals(value)) {
				log.error("敏感词过滤:" + value + ".key:" + key);
				count ++;
			}
		}
		return value;
	}
}
